home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
TCL1
/
MIDI_MAN
/
CMIDITIM.C
< prev
next >
Wrap
Text File
|
1992-03-07
|
8KB
|
252 lines
//--- CMIDITimePort.c ------------------------------------------------------------------
// Copyright ⌐ Paul Ferguson, 1990, 1991, 1992. All rights reserved.
//
// Description:
// CMIDITimePort.c defines a MIDI Manager time port object.
//
// For use with THINK C 5.0, the accompanying THINK Class Library (TCL), and MIDI
// Manager 2.0. Refer to the accompanying Microsoft Word document for complete
// details about MIDI Manager objects.
//
// If you have comments or questions about this code, you can reach me on
// CompuServe at 70441,3055.
//
//--------------------------------------------------------------------------------------
//---- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE ----
//--------------------------------------------------------------------------------------
// If you are not familiar with programming the Apple MIDI Manager, refer to the
// "MIDI Management Tools" Version 2.0, available from APDA. You MUST have the
// software (MIDI.H and the library) from this package in order to use these objects.
// It will not work without this.
//--------------------------------------------------------------------------------------
// REVISION HISTORY:
// August ??, 1990 - Original release (1.0).
// November 5, 1990 - Added checks for midiMgrVer to most methods.
// August 1991 - updated for THINK C 5.0 as version 2.0
//--------------------------------------------------------------------------------------
#include "CMIDITimePort.h" // This code's header file
#include <CApplication.h>
extern CApplication *gApplication; // Used in SetConnection
extern OSType gSignature; // Used to register client
#define noClient ' ' // The UnClient
extern CMIDIClient * gMIDIClient;
//--- CMIDITimePort methods ------------------------------------------
// Methods for a MIDI Manager time port.
// Superclass CMIDIPort
// Subclasses None
//--------------------------------------------------------------------
OSErr CMIDITimePort::IMIDITimePort(StringPtr theName,
OSType thePortID,
Boolean theVisibleFlag,
short theFormat)
{
MIDIPortParams portParams;
register MIDIPortParams * portPPtr = &portParams;
OSErr theResult;
portPPtr->portID = thePortID;
portPPtr->portType = midiPortTypeTime;
if (theVisibleFlag == FALSE)
{
if (itsVersion >= 0x0200)
portPPtr->portType |= midiPortInvisible; // Use 2.0 preferred syntax
else
portPPtr->portType = midiPortTypeTimeInv; // Use 1.x syntax
}
portPPtr->timeBase = 0;
portPPtr->offsetTime = 0;
portPPtr->readHook = (Ptr) 0;
portPPtr->refCon = 0;
portPPtr->initClock.sync = midiInternalSync; // Always start out internal
portPPtr->initClock.curTime = 0;
portPPtr->initClock.format = theFormat;
BlockMove(theName, portPPtr->name, theName[0]+1);
theResult = IMIDIPort(portPPtr, 0);
if (theResult == noErr)
{
UpdateSync(); // Check for time base connections
}
return (theResult);
}
//--- CMIDITimePort::LoadPatches --------------------------------------------
// Load any time patches, and make connections.
//---------------------------------------------------------------------------
OSErr CMIDITimePort::LoadPatches(ResType theResType, short theResID)
{
OSErr theErr = noErr;
MIDIPortInfoHdl rezPortInfoH, ourPortInfoH;
short i;
Str255 theName;
if ( itsVersion == 0 ) // Couldn╒t open the MIDI Manager for some reason
return (ErrNoMIDI);
if (itsResult != noErr)
return (itsResult);
// Check for virtual connections stored in a resource.
GetPortName(theName);
rezPortInfoH = (MIDIPortInfoHdl) GetResource(theResType, theResID);
if ( (rezPortInfoH) && (GetHandleSize((Handle) rezPortInfoH) > 0) )
{
HLock((Handle) rezPortInfoH);
ourPortInfoH = GetPortInfo();
if ((**ourPortInfoH).type == (**rezPortInfoH).type) // Is this resource a time port?
{
if ((**rezPortInfoH).timeBase.clientID != noClient) // Were we supposed to be synchronized
{ // to another client?
theErr = MIDIConnectTime(
(**rezPortInfoH).timeBase.clientID, // Yes, make that client our time base
(**rezPortInfoH).timeBase.portID,
gSignature,
itsPortID);
if (theErr != midiVConnectErr) // Is client still signed in?
SetExternalSync();
}
// Were we someone else's time base? Ch
for (i = 0; i < (**rezPortInfoH).numConnects; i++)
{
theErr = MIDIConnectTime(gSignature, // We are the time base for them
itsPortID,
(**rezPortInfoH).cList[i].clientID,
(**rezPortInfoH).cList[i].portID);
if (theErr) break;
}
}
HUnlock((Handle) rezPortInfoH);
ReleaseResource((Handle) rezPortInfoH);
}
return (theErr);
}
//--- CMIDITimePort::UpdateSync ---------------------------------------
// Set internal or external time base synchronization depending on
// current connections. It returns the current synchronization setting
// (same as GetSync).
//--------------------------------------------------------------------
short CMIDITimePort::UpdateSync(void)
{
MIDIPortInfoHdl thePortInfoH;
register short theResult;
thePortInfoH = GetPortInfo();
if (thePortInfoH)
{
theResult = GetSync();
if ( (**thePortInfoH).timeBase.clientID != noClient )
{
if (theResult != midiExternalSync)
SetExternalSync();
}
else
{
if (theResult != midiInternalSync)
SetInternalSync();
}
DisposHandle(thePortInfoH);
}
return (itsVersion ? MIDIGetSync(itsRefNum) : -1);
}
//--- CMIDITimePort:: trivial methods --------------------------
short CMIDITimePort::GetSync(void)
{
return(itsVersion ? MIDIGetSync(itsRefNum) : -1);
}
void CMIDITimePort::SetExternalSync(void)
{
if (itsVersion)
MIDISetSync(itsRefNum, midiExternalSync);
}
void CMIDITimePort::SetInternalSync(void)
{
if (itsVersion)
MIDISetSync(itsRefNum, midiInternalSync);
}
long CMIDITimePort::GetCurTime(void)
{
return(itsVersion ? MIDIGetCurTime(itsRefNum) : 0);
}
void CMIDITimePort::SetCurTime(long theTime)
{
if (itsVersion)
MIDISetCurTime(itsRefNum, theTime);
}
void CMIDITimePort::StartTime(void)
{
if (itsVersion)
MIDIStartTime(itsRefNum);
}
void CMIDITimePort::StopTime(void)
{
if (itsVersion)
MIDIStopTime(itsRefNum);
}
long CMIDITimePort::GetOffsetTime(void)
{
return (itsVersion ? MIDIGetOffsetTime(itsRefNum) : 0);
}
void CMIDITimePort::SetOffsetTime(long theOffset)
{
if (itsVersion)
MIDISetOffsetTime(itsRefNum, theOffset);
}
void CMIDITimePort::WakeUp(long theBaseTime, long thePeriod, ProcPtr theTimeProc)
{
if (itsVersion)
MIDIWakeUp(itsRefNum, theBaseTime, thePeriod, theTimeProc);
}
//--- CMIDITimePort::Perform --------------------------------------
// This turns the time port into a CChore, so that you can call
// gApplication->AssignIdleChore() with this object.
//-----------------------------------------------------------------
void CMIDITimePort::Perform(long * maxSleep)
{
if ( gMIDIClient->WorldChanged() )
UpdateSync();
}
//--- CMIDITimePort::SetConnection --------------------------------
// This sets the connection procedure. Note that for pre-2.0 or
// a NULL connectionProc, the previous method, Perform(), will
// called at idle time, checking for a change in the wind.
//-----------------------------------------------------------------
void CMIDITimePort::SetConnection(ProcPtr theConnectionProc)
{
if ((gMIDIClient->GetShortVerNum() < 0x200 ) // If pre-2.0
|| (theConnectionProc == NULL) ) // or a null pointer
gApplication->AssignIdleChore( (CChore *) this );
else // else use connection proc
SetConnectionProc(theConnectionProc, GetRefCon());
}
// end of CMIDITimePort.c